const DoublyLinkedList = require("../template.js")

/** 严格测试：测试 prev 和 next 指针的正确性 */
function strictTests() {
  console.log("===== 严格测试开始 =====")
  
  // 测试1：append 的 prev 指针
  const link1 = new DoublyLinkedList()
  link1.append(1).append(2).append(3)
  console.log(
    "6.1 append的prev指针:",
    link1.tail.prev.value === 2 && 
    link1.tail.prev.prev.value === 1 &&
    link1.head.next.prev.value === 1
  )
  
  // 测试2：removeTail 只有一个节点时
  const link2 = new DoublyLinkedList()
  link2.append(1)
  try {
    link2.removeTail()
    console.log(
      "6.2 removeTail单节点:",
      link2.isEmpty() && link2.head === null && link2.tail === null
    )
  } catch(e) {
    console.log("6.2 removeTail单节点: false (报错:", e.message + ")")
  }
  
  // 测试3：removeHead 只有一个节点时
  const link3 = new DoublyLinkedList()
  link3.append(1)
  try {
    link3.removeHead()
    console.log(
      "6.3 removeHead单节点:",
      link3.isEmpty() && link3.head === null && link3.tail === null
    )
  } catch(e) {
    console.log("6.3 removeHead单节点: false (报错:", e.message + ")")
  }
  
  // 测试4：removeByValue 删除头节点（必须检查 size！）
  const link4 = DoublyLinkedList.fromArray([1, 2, 3])
  try {
    link4.removeByValue(1)
    console.log(
      "6.4 removeByValue删除头节点:",
      link4.head.value === 2 && link4.head.prev === null && link4.size === 2
    )
  } catch(e) {
    console.log("6.4 removeByValue删除头节点: false (报错:", e.message + ")")
  }
  
  // 测试5：removeByValue 删除尾节点（必须检查 size！）
  const link5 = DoublyLinkedList.fromArray([1, 2, 3])
  try {
    link5.removeByValue(3)
    console.log(
      "6.5 removeByValue删除尾节点:",
      link5.tail.value === 2 && link5.tail.next === null && link5.size === 2
    )
  } catch(e) {
    console.log("6.5 removeByValue删除尾节点: false (报错:", e.message + ")")
  }
  
  // 测试6：removeByIndex 删除头节点（必须检查 size！）
  const link6 = DoublyLinkedList.fromArray([1, 2, 3])
  try {
    link6.removeByIndex(0)
    console.log(
      "6.6 removeByIndex删除头节点:",
      link6.head.value === 2 && link6.head.prev === null && link6.size === 2
    )
  } catch(e) {
    console.log("6.6 removeByIndex删除头节点: false (报错:", e.message + ")")
  }
  
  // 测试7：removeByIndex 删除尾节点（必须检查 size！）
  const link7 = DoublyLinkedList.fromArray([1, 2, 3])
  try {
    link7.removeByIndex(2)
    console.log(
      "6.7 removeByIndex删除尾节点:",
      link7.tail.value === 2 && link7.tail.next === null && link7.size === 2
    )
  } catch(e) {
    console.log("6.7 removeByIndex删除尾节点: false (报错:", e.message + ")")
  }
  
  // 测试8：insertByValue 在尾节点后插入（检查 size 和 tail）
  const link8 = DoublyLinkedList.fromArray([1, 2, 3])
  try {
    link8.insertByValue(3, 4)
    console.log(
      "6.8 insertByValue在尾节点后插入:",
      link8.tail.value === 4 && 
      link8.tail.prev.value === 3 &&
      link8.size === 4 &&
      link8.tail.next === null
    )
  } catch(e) {
    console.log("6.8 insertByValue在尾节点后插入: false (报错:", e.message + ")")
  }
  
  // 测试9：insertByIndex 在尾节点后插入（检查 size 和 tail）
  const link9 = DoublyLinkedList.fromArray([1, 2, 3])
  try {
    link9.insertByIndex(2, 4) // 在索引2的节点后插入
    console.log(
      "6.9 insertByIndex在尾节点后插入:",
      link9.tail.value === 4 && 
      link9.tail.prev.value === 3 &&
      link9.size === 4 &&
      link9.tail.next === null
    )
  } catch(e) {
    console.log("6.9 insertByIndex在尾节点后插入: false (报错:", e.message + ")")
  }
  
  // 测试10：insertByValue 空链表时不会重复计数
  const link10 = new DoublyLinkedList()
  try {
    link10.insertByValue(1, 1) // 空链表时
    console.log(
      "6.10 insertByValue空链表计数:",
      link10.size === 1
    )
  } catch(e) {
    console.log("6.10 insertByValue空链表计数: false (报错:", e.message + ")")
  }
  
  // 测试11：removeByIndex 删除中间节点（不应该重复减 size）
  const link11 = DoublyLinkedList.fromArray([1, 2, 3, 4, 5])
  try {
    link11.removeByIndex(2) // 删除索引2（值为3）
    console.log(
      "6.11 removeByIndex删除中间节点size:",
      link11.size === 4 && 
      DoublyLinkedList.toString(link11) === "1,2,4,5"
    )
  } catch(e) {
    console.log("6.11 removeByIndex删除中间节点size: false (报错:", e.message + ")")
  }
  
  // 测试12：removeByValue 删除中间节点（不应该重复减 size）
  const link12 = DoublyLinkedList.fromArray([1, 2, 3, 4, 5])
  try {
    link12.removeByValue(3) // 删除值为3的节点
    console.log(
      "6.12 removeByValue删除中间节点size:",
      link12.size === 4 && 
      DoublyLinkedList.toString(link12) === "1,2,4,5"
    )
  } catch(e) {
    console.log("6.12 removeByValue删除中间节点size: false (报错:", e.message + ")")
  }
  
  // 测试13：insertByValue 在中间插入，检查新节点的下一个节点的 prev 指针
  const link13 = DoublyLinkedList.fromArray(['A', 'B', 'C'])
  try {
    link13.insertByValue('A', 'X') // 在 A 后插入 X，链表变为 A X B C
    const nodeX = link13.findByIndex(1) // X 节点
    const nodeB = link13.findByIndex(2) // B 节点
    console.log(
      "6.13 insertByValue中间插入prev指针:",
      nodeX.value === 'X' &&
      nodeB.value === 'B' &&
      nodeB.prev === nodeX && // ← 关键：B.prev 应该指向 X
      nodeX.next === nodeB &&
      DoublyLinkedList.toString(link13) === 'A,X,B,C'
    )
  } catch(e) {
    console.log("6.13 insertByValue中间插入prev指针: false (报错:", e.message + ")")
  }
  
  // 测试14：insertByIndex 在中间插入，检查新节点的下一个节点的 prev 指针
  const link14 = DoublyLinkedList.fromArray(['A', 'B', 'C'])
  try {
    link14.insertByIndex(0, 'X') // 在索引0（A）后插入 X，链表变为 A X B C
    const nodeX = link14.findByIndex(1) // X 节点
    const nodeB = link14.findByIndex(2) // B 节点
    console.log(
      "6.14 insertByIndex中间插入prev指针:",
      nodeX.value === 'X' &&
      nodeB.value === 'B' &&
      nodeB.prev === nodeX && // ← 关键：B.prev 应该指向 X
      nodeX.next === nodeB &&
      DoublyLinkedList.toString(link14) === 'A,X,B,C'
    )
  } catch(e) {
    console.log("6.14 insertByIndex中间插入prev指针: false (报错:", e.message + ")")
  }
  
  // 测试15：从插入的新节点的下一个节点反向遍历，应该能找到新节点
  const link15 = DoublyLinkedList.fromArray([1, 2, 3, 4, 5])
  try {
    link15.insertByValue(2, 99) // 在 2 后插入 99，链表变为 1 2 99 3 4 5
    const node3 = link15.findByValue(3) // 找到值为 3 的节点
    const prevNode = node3.prev // 从 3 向前找，应该是 99
    console.log(
      "6.15 插入后反向遍历验证:",
      prevNode.value === 99 && // ← 关键：3 的 prev 应该是 99
      prevNode.prev.value === 2 &&
      DoublyLinkedList.toString(link15) === '1,2,99,3,4,5'
    )
  } catch(e) {
    console.log("6.15 插入后反向遍历验证: false (报错:", e.message + ")")
  }
  
  console.log("--------------------")
}

strictTests()

module.exports = strictTests

